/* * citygml4j - The Open Source Java API for CityGML * https://github.com/citygml4j * * Copyright 2013-2017 Claus Nagel <claus.nagel@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.citygml4j.builder.jaxb.xml.validation; import java.io.IOException; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.ValidationEvent; import javax.xml.bind.ValidationEventHandler; import javax.xml.bind.helpers.ValidationEventImpl; import javax.xml.bind.helpers.ValidationEventLocatorImpl; import javax.xml.transform.dom.DOMSource; import javax.xml.validation.Schema; import org.citygml4j.builder.jaxb.JAXBBuilder; import org.citygml4j.builder.jaxb.marshal.JAXBMarshaller; import org.citygml4j.model.citygml.ade.ADEComponent; import org.citygml4j.model.module.ModuleContext; import org.citygml4j.model.module.citygml.CityGMLVersion; import org.citygml4j.xml.schema.SchemaHandler; import org.citygml4j.xml.validation.CityGMLValidateException; import org.citygml4j.xml.validation.Validator; import org.w3c.dom.Element; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; public class JAXBValidator implements Validator { private final JAXBBuilder builder; private ValidationSchemaHandler validationSchemaHandler; private ValidationEventHandler validationEventHandler; public JAXBValidator(JAXBBuilder builder) throws CityGMLValidateException { this.builder = builder; try { validationSchemaHandler = new ValidationSchemaHandler(SchemaHandler.newInstance()); } catch (SAXException e) { throw new CityGMLValidateException("Caused by: ", e); } } public JAXBValidator(JAXBBuilder builder, SchemaHandler schemaHandler) { this.builder = builder; validationSchemaHandler = new ValidationSchemaHandler(schemaHandler); } public SchemaHandler getSchemaHandler() { return validationSchemaHandler.getSchemaHandler(); } public ValidationEventHandler getValidationEventHandler() { return validationEventHandler; } public void setSchemaHandler(SchemaHandler schemaHandler) { if (schemaHandler == null) throw new IllegalArgumentException("schema handler may not be null."); validationSchemaHandler.setSchemaHandler(schemaHandler); } public void setValidationEventHandler(ValidationEventHandler validationEventHandler) { this.validationEventHandler = validationEventHandler; } public void validate(Object object, CityGMLVersion version) throws CityGMLValidateException { validate(object, new ModuleContext(version)); } public void validate(Object object, ModuleContext moduleContext) throws CityGMLValidateException { try { Schema schema = validationSchemaHandler.getSchema(); if (object instanceof ADEComponent) object = ((ADEComponent)object).getContent(); if (object instanceof Element) { javax.xml.validation.Validator validator = schema.newValidator(); if (validationEventHandler != null) validator.setErrorHandler(new ErrorHandler2ValidationEventHandler()); try { validator.validate(new DOMSource((Element)object)); } catch (IOException e) { throw new CityGMLValidateException("Caused by: ", e); } } else { JAXBMarshaller marshaller = builder.createJAXBMarshaller(moduleContext); Object jaxb = marshaller.marshalJAXBElement(object); if (jaxb != null) { try { Marshaller m = builder.getJAXBContext().createMarshaller(); m.setSchema(schema); if (validationEventHandler != null) m.setEventHandler(validationEventHandler); m.marshal(jaxb, new DefaultHandler()); } catch (JAXBException e) { throw new CityGMLValidateException("Caused by: ", e); } } else throw new CityGMLValidateException("failed to marshal citygml4j object to JAXB - validation aborted."); } } catch (SAXException e) { throw new CityGMLValidateException("Caused by: ", e); } } private final class ErrorHandler2ValidationEventHandler implements ErrorHandler { public void fatalError(SAXParseException exception) throws SAXException { handleValidationEvent(exception, ValidationEvent.FATAL_ERROR); } public void warning(SAXParseException exception) throws SAXException { handleValidationEvent(exception, ValidationEvent.WARNING); } public void error(SAXParseException exception) throws SAXException { handleValidationEvent(exception, ValidationEvent.ERROR); } private void handleValidationEvent(SAXParseException exception, int severity) throws SAXException { if (!validationEventHandler.handleEvent( new ValidationEventImpl( severity, exception.getMessage(), new ValidationEventLocatorImpl(), exception.getCause()))) throw exception; } } }